package com.shanzhi.connection.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DocumentSplitUtils {
    public static Map<String, List<String>> processText(String text) {
        List<String> cleanedSections = process(text);
        // 新增：执行最终的结构化合并
        cleanedSections = mergeSmallSections(cleanedSections);

        int totalLength = 0;
        for (String section : cleanedSections) {
            System.out.println("每一段的字符长度+" + ++totalLength + "： " + section.length());
        }


        Map<String, List<String>> result = new HashMap<>();
        result.put("text", cleanedSections);

        return result;
    }


    private static String extractHeadingNumber(String line) {
        if (line == null || line.trim().isEmpty()) return "";
        String cleaned = line.trim();
        Pattern pattern = Pattern.compile("^#?\\s*(\\d+(?:\\.\\d+)*)");
        Matcher matcher = pattern.matcher(cleaned);
        return matcher.find() ? matcher.group(1) : "";
    }

    public static List<String> mergeSmallSections(List<String> sections) {
        List<String> result = new ArrayList<>(sections);

        for (int i = result.size() - 1; i >= 0; i--) {
            String current = result.get(i);

            if (current.length() >= 100) continue;

            String currentNum = extractHeadingNumber(current);

            boolean merged = false;

            // 查看下一项是否是当前项的子项
            if (i + 1 < result.size()) {
                String next = result.get(i + 1);
                String nextNum = extractHeadingNumber(next);

                if (isChildOf(nextNum, currentNum)) {
                    result.set(i + 1, current + "\n\n" + next);
                    result.remove(i);
                    merged = true;
                }
            }

            // 如果没有匹配到子项，则尝试合并到前一项
            if (!merged && i > 0) {
                String prev = result.get(i - 1);
                String prevNum = extractHeadingNumber(prev);

                if (isChildOf(currentNum, prevNum)) {
                    result.set(i - 1, prev + "\n\n" + current);
                    result.remove(i);
                    merged = true;
                }
            }

            // 默认合并到下一项
            if (!merged && i + 1 < result.size()) {
                String next = result.get(i + 1);
                result.set(i + 1, current + "\n\n" + next);
                result.remove(i);
            }
        }

        return result;
    }

    private static boolean isChildOf(String child, String parent) {
        if (child == null || parent == null) return false;
        // 父级必须是子级的前缀，且子级比父级多一级
        return child.startsWith(parent + ".") && child.split("\\.").length == parent.split("\\.").length + 1;
    }

    public static List<String> process(String originalText) {
        String text = preprocess(originalText);

        // 初级分割处理（按一级标题）
        List<String> sections = splitByPrimaryHeadings(text);

        // 后处理阶段
        List<String> processed = postProcess(sections);

        // 合并小于500字符的段落到下一段
        List<String> merged = mergeSmallParagraphs(processed);

        // 对大于3000字符的段落进行递归拆分
        List<String> finalSections = new ArrayList<>();
        for (String sec : processed) {
            if (sec.length() <= 3000) {
                finalSections.add(sec);
            } else {
                List<String> splitResult = splitByHeadings(sec);
                if (splitResult.isEmpty()) {
                    // 如果仍大于3000，尝试使用数字编号方式拆分
                    List<String> list = splitByNumbering(sec);
                    for (String part : list) {
                        if (part.length() > 3000) {
                            System.out.println("段落长度大于3000，尝试使用数字编号方式拆分");
                        }
                        finalSections.add(part);
                    }

                } else {
                    for (String part : splitResult) {
                        if (part.length() > 3000) {
                            // 如果仍大于3000，尝试使用数字编号方式拆分
                            List<String> list = splitByNumbering(sec);
                            for (String partSec : list) {
                                if (partSec.length() > 3000) {
                                    System.out.println("段落长度大于3000，尝试使用数字编号方式拆分");
                                }
                                finalSections.add(partSec);
                            }
                        } else {
                            finalSections.add(part);
                        }
                    }
                }
            }
        }

        return filterEmpty(finalSections);
    }

    private static String preprocess(String text) {
        text = text.replaceAll("(?m)^\\s*$", ""); // 移除空行
        text = text.replaceAll("(?m)^\\s*# ", "# "); // 标准化标题格式
        return text;
    }

    private static List<String> splitByPrimaryHeadings(String text) {
        List<String> sections = new ArrayList<>();
        List<String> current = new ArrayList<>();

        for (String line : text.split("\n")) {
            if (line.trim().startsWith("# ")) {
                if (!current.isEmpty()) {
                    sections.add(String.join("\n", current));
                }
                current.clear();
                current.add(line);
            } else {
                current.add(line);
            }
        }

        if (!current.isEmpty()) {
            sections.add(String.join("\n", current));
        }

        return sections;
    }

    private static List<String> postProcess(List<String> sections) {
        List<String> processed = new ArrayList<>();
        for (String section : sections) {
            String cleaned = section
                    .replaceAll("(?m)^\\s*", "")
                    .replaceAll("(?m)\\s+$", "")
                    .replaceAll("(?m)\n{3,}", "\n\n");

            if (cleaned.split("\n").length > 5 && !cleaned.startsWith("# ")) {
                String[] parts = cleaned.split("(?m)(^## |^### |^#### )");
                if (parts.length > 1) {
                    Collections.addAll(processed, Arrays.copyOfRange(parts, 1, parts.length));
                } else {
                    processed.add(cleaned);
                }
            } else {
                processed.add(cleaned);
            }
        }
        return processed;
    }

    /**
     * 合并小于500字符的段落，持续合并直到段落≥500或无后续段落，同时避免段落超过3000字符
     *
     * @param sections
     * @return
     */
    private static List<String> mergeSmallParagraphs(List<String> sections) {
        List<String> result = new ArrayList<>();
        int i = 0;

        while (i < sections.size()) {
            String current = sections.get(i);

            // 如果当前段落已经 >= 500 或者是最后一段，则直接加入结果
            if (current.length() >= 500 || i == sections.size() - 1) {
                result.add(current);
                i++;
                continue;
            }

            // 尝试与后续段落合并，直到满足长度或无法合并
            int j = i + 1;
            while (j < sections.size()) {
                String next = sections.get(j);
                if (current.length() + next.length() + 2 > 3000) {
                    break; // 超过最大限制，停止合并
                }
                current += "\n\n" + next;

                if (current.length() >= 500) {
                    break; // 达到最小长度要求，停止合并
                }
                j++;
            }

            result.add(current); // 添加合并后的段落
            i = j + 1; // 跳过已合并的段落
        }

        return result;
    }

    private static List<String> splitByHeadings(String text) {
        return splitByHeadingsRecursive(text, 2);
    }

    private static List<String> splitByHeadingsRecursive(String text, int level) {
        String patternStr = String.format("(?m)(^#{%d} )", level);
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(text);
        boolean found = matcher.find();

        if (!found) {
            if (level < 6) {
                return splitByHeadingsRecursive(text, level + 1);
            } else {
                return Collections.emptyList();
            }
        }

        List<String> result = new ArrayList<>();
        String[] parts = pattern.split(text);
        for (int i = 1; i < parts.length; i += 2) {
            String title = parts[i];
            String content = parts[i + 1];
            result.add(title.trim() + "\n" + content.trim());
        }

        return result;
    }

    private static List<String> splitByNumbering(String text) {
        List<String> sections = new ArrayList<>();
        List<String> current = new ArrayList<>();

        String regex = "^(?:\\d+(?:\\.\\d+)+|[A-Z]\\.\\d+(?:\\.\\d+)*).*";

        for (String line : text.split("\n")) {
            if (line.trim().matches(regex)) {
                if (!current.isEmpty()) {
                    sections.add(String.join("\n", current));
                }
                current.clear();
                current.add(line);
            } else {
                current.add(line);
            }
        }

        if (!current.isEmpty()) {
            sections.add(String.join("\n", current));
        }


        return mergeSmallParagraphs(sections);
    }

    private static List<String> filterEmpty(List<String> list) {
        List<String> result = new ArrayList<>();
        for (String s : list) {
            if (s != null && !s.trim().isEmpty()) {
                result.add(s);
            }
        }
        return result;
    }

    // 示例主方法调用入口
    public static void main(String[] args) {
        File file = new File("D:\\java_tool_workspace\\ConnectionTool\\1.json");
        try {
            String text = FileUtils.readFileToString(file, "UTF-8");
            JSONObject jsonObject = JSONObject.parseObject(text);
            String text_object = (String) jsonObject.get("text");
            Map<String, List<String>> result = processText(text_object);

            // 将结果写入 2.json
            String jsonOutput = JSON.toJSONString(result, true); // 格式化输出
            Files.write(Paths.get("D:\\java_tool_workspace\\ConnectionTool\\2.json"), jsonOutput.getBytes(StandardCharsets.UTF_8));

            System.out.println("结果已写入 2.json");

//            System.out.println(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
